package org.dreamwork.floatingball.util;

import android.app.Service;
import android.content.Context;
import android.graphics.PixelFormat;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

import org.dreamwork.floatingball.R;
import org.dreamwork.floatingball.ui.ConfirmPanel;
import org.dreamwork.floatingball.ui.FloatingBall;

import java.util.concurrent.ExecutorService;

import static org.dreamwork.floatingball.service.FloatingBallService2.D;

/**
 * Created by seth.yang on 2017/3/31
 */

public class ViewManager implements
        FloatingBall.IViewSizeChangeListener, View.OnClickListener {
    private static final String TAG = "ViewManager";

    private FloatingBall ball;
    private WindowManager mManager;
    private ConfirmPanel panel;
    private int WIDTH, HEIGHT;

    private WindowManager.LayoutParams floatBallParams, panelParams;

    private View.OnTouchListener touchListener = new View.OnTouchListener() {
        float startX;
        float startY;
        float tempX;
        float tempY;

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    startX = event.getRawX();
                    startY = event.getRawY();

                    tempX = event.getRawX();
                    tempY = event.getRawY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    float x = event.getRawX() - startX;
                    float y = event.getRawY() - startY;
                    //计算偏移量，刷新视图
                    floatBallParams.x += x;
                    floatBallParams.y += y;
                    ball.setDragging (true);
                    mManager.updateViewLayout(ball, floatBallParams);
                    startX = event.getRawX();
                    startY = event.getRawY();
                    break;
                case MotionEvent.ACTION_UP:
                    //判断松手时View的横坐标是靠近屏幕哪一侧，将View移动到依靠屏幕
                    float endX = event.getRawX();
                    float endY = event.getRawY();
                    if (endX < WIDTH / 2) {
                        endX = 0;
                    } else {
                        endX = WIDTH - ball.getCurrentWidth ();
                    }
                    floatBallParams.x = (int) endX;
                    ball.setDragging (false);
                    mManager.updateViewLayout(ball, floatBallParams);
                    //如果初始落点与松手落点的坐标差值超过6个像素，则拦截该点击事件
                    //否则继续传递，将事件交给OnClickListener函数处理
                    if (Math.abs(endX - tempX) > 6 && Math.abs(endY - tempY) > 6) {
                        return true;
                    }
                    break;
            }
            return false;
        }
    };

    private static ViewManager instance;

    public static ViewManager getInstance (Context context, ExecutorService pool) {
        if (instance == null) {
            instance = new ViewManager (context, pool);
        }
        return instance;
    }

    public static ViewManager getInstance () {
        return instance;
    }

    private ViewManager (Context context, ExecutorService pool) {
        init (context, pool);
    }

    private void init (Context context, ExecutorService pool) {
        mManager = (WindowManager) context.getSystemService (Context.WINDOW_SERVICE);
        LayoutInflater inflater = (LayoutInflater)context.getSystemService (Service.LAYOUT_INFLATER_SERVICE);
        ball = (FloatingBall) inflater.inflate (R.layout.floating_panel, null);
        ball.guiInit ();
        ball.setOnTouchListener (touchListener);
        ball.setPool (pool);
        ball.setViewSizeChangedListener (this);

        panel = (ConfirmPanel) inflater.inflate (R.layout.confirm_dialog, null);
        panel.guiInit ();
        panel.setOnPowerOffListener (this);
        panel.setOnRebootListener (this);
        panel.setOnClickListener (this);

        DisplayMetrics m = new DisplayMetrics ();
        mManager.getDefaultDisplay ().getMetrics (m);
        WIDTH = m.widthPixels;
        HEIGHT = m.heightPixels;

        floatBallParams         = new WindowManager.LayoutParams ();
        floatBallParams.alpha   = .5f;
        floatBallParams.width   = ball.getCurrentWidth ();
        floatBallParams.height  = FloatingBall.HEIGHT;
        floatBallParams.gravity = Gravity.LEFT | Gravity.TOP;
        floatBallParams.type    = WindowManager.LayoutParams.TYPE_TOAST;
        floatBallParams.flags   = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                                  WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
        floatBallParams.format  = PixelFormat.RGBA_8888;
        floatBallParams.x       = WIDTH - ball.getCurrentWidth ();
        floatBallParams.y       = HEIGHT - FloatingBall.HEIGHT;

        panelParams             = new WindowManager.LayoutParams ();
        panelParams.width       = WIDTH;
        panelParams.height      = HEIGHT;
        panelParams.gravity     = Gravity.CENTER;
        panelParams.type        = WindowManager.LayoutParams.TYPE_TOAST;
        panelParams.flags       = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
        panelParams.format      = PixelFormat.RGBA_8888;
    }

    public void showBall () {
        mManager.addView (ball, floatBallParams);
    }

    public void showDialog () {
        if (panel != null)
            mManager.addView (panel, panelParams);
    }

    @Override
    public void notifyViewSizeChanged (FloatingBall ball) {
        floatBallParams.width = ball.getCurrentWidth ();
        if (floatBallParams.x < WIDTH / 2) {
            floatBallParams.x = 0;
        } else {
            floatBallParams.x = WIDTH - ball.getCurrentWidth ();
        }
        mManager.updateViewLayout (ball, floatBallParams);
    }

    public void clear () {
        if (D) {
            Log.d (TAG, "clear");
        }
        ball.clear ();
    }

    @Override
    public void onClick (View v) {
        switch (v.getId ()) {
            case R.id.btn_power_off :
                if (D) {
                    Log.d (TAG, "power off pressed");
                }
                break;
            case R.id.btn_reboot :
                if (D) {
                    Log.d (TAG, "reboot pressed");
                }
                break;
            case R.id.confirm_panel :
                if (D) {
                    Log.d (TAG, "cancel triggered");
                }
                break;
        }
        if (panel != null)
            mManager.removeView (panel);
    }
}